package vcp.server.DAO;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import vcp.entity.User;
import vcp.enums.UserType;
import vcp.server.DBAdapter;
import vcp.server.DAO.interfaces.IGenericDAO;
import vcp.server.utility.Constants.TableNames;
import vcp.server.utility.Constants.UserTable;
import vcp.server.utility.SQLQueries;
/**
 * <p> user DAO class , all sql queries for user are implemented </p>
 * @author VCP team
 *
 */
public class UserDAO implements IGenericDAO <User, Void>
{
	/****************************************************************************************************************************
	 *** Public methods ***
	 ****************************************************************************************************************************/
	/**
	 * find all logged in users
	 * @return list of users
	 */
	public List <User> findAllLoggedIn ()
	{
		String query =
				String.format(
						SQLQueries.SELECT_ALL_FROM_SINGLETABLE
						, TableNames.USER);

		List <User> listOfLoggedInUsers = null;
		try
		{
			ResultSet set = DBAdapter.getAdapter().find(query);
			listOfLoggedInUsers = new ArrayList <User>();

			while ( set.next() )
			{
				if ( set.getBoolean(UserTable.IS_LOGGED_IN) )
				{
					User user = this.create();

					user.setUserID(set.getInt(UserTable.ID));
					user.setPassword(set.getString(UserTable.PASSWORD));
					user.setUserFirstName(set.getString(UserTable.FIRST_NAME));
					user.setUserLastName(set.getString(UserTable.LAST_NAME));
					user.setUserType(UserType.convert(set.getString(UserTable.TYPE)));
					user.setUserEmail(set.getString(UserTable.EMAIL));
					user.setLoggedIn(set.getBoolean(UserTable.IS_LOGGED_IN));

					listOfLoggedInUsers.add(user);
				}
			}
		}
		catch ( SQLException e )
		{
			e.printStackTrace();
		}
		return listOfLoggedInUsers;
	}
	/**
	 * updates the status of logged in field in table
	 * @param ID
	 * @param loggedIn
	 * @return true if success
	 */
	public boolean updatedLoggedInStatus ( int ID, boolean loggedIn )
	{
		boolean success = false;

		String sqlQuery =
				String.format(
						SQLQueries.UPDATE__TABLENAME__SET__SINGLEVALUE__WHERE__COMPARE_
						, TableNames.USER
						, UserTable.IS_LOGGED_IN + "=" + loggedIn
						, UserTable.ID + "=" + String.valueOf(ID));
		success = this.refresh(sqlQuery);

		return success;
	}

	/****************************************************************************************************************************
	 *** IGenericDAO methods ***
	 ****************************************************************************************************************************/

	/**
	 * Not implemented
	 */
	@Override
	public Integer findMaxID ()
	{
		return null;
	}

	@Override
	public User create ()
	{
		return new User();
	}

	/**
	 * not implemented
	 */

	@Override
	public User findByEntity ( Void entity )
	{
		return null;
	}

	@Override
	public User findByID ( int ID )
	{
		return this.findByID(String.valueOf(ID));
	}

	@Override
	public User findByID ( String ID )
	{
		String query =
				String.format(
						SQLQueries.SELECT_ALL_FROM__SINGLETABLE__WHERE__COMPARE_
						, TableNames.USER
						, UserTable.ID + "=" + ID);

		User user = null;
		try
		{
			ResultSet set = DBAdapter.getAdapter().find(query);
			if ( set.next() )
			{
				user = this.create();

				user.setUserID(set.getInt(UserTable.ID));
				user.setPassword(set.getString(UserTable.PASSWORD));
				user.setUserFirstName(set.getString(UserTable.FIRST_NAME));
				user.setUserLastName(set.getString(UserTable.LAST_NAME));
				user.setUserType(UserType.convert(set.getString(UserTable.TYPE)));
				user.setUserEmail(set.getString(UserTable.EMAIL));
			}
		}
		catch ( SQLException e )
		{
			e.printStackTrace();
		}
		return user;
	}

	@Override
	public List <User> findAll ( Void info )
	{
		String query =
				String.format(
						SQLQueries.SELECT_ALL_FROM_SINGLETABLE
						, TableNames.USER);

		List <User> listOfUsers = null;
		try
		{
			ResultSet set = DBAdapter.getAdapter().find(query);
			listOfUsers = new ArrayList <User>();
			while ( set.next() )
			{
				User user = this.create();

				user.setUserID(set.getInt(UserTable.ID));
				user.setPassword(set.getString(UserTable.PASSWORD));
				user.setUserFirstName(set.getString(UserTable.FIRST_NAME));
				user.setUserLastName(set.getString(UserTable.LAST_NAME));
				user.setUserType(UserType.convert(set.getString(UserTable.TYPE)));
				user.setUserEmail(set.getString(UserTable.EMAIL));

				listOfUsers.add(user);
			}
		}
		catch ( SQLException e )
		{
			e.printStackTrace();
		}
		return listOfUsers;
	}

	@Override
	public boolean save ( User entity )
	{
		boolean result = false;
		String valuesSet =
				String.format(
						"%d,\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",%d"
						, entity.getUserID()
						, entity.getPassword()
						, entity.getUserFirstName()
						, entity.getUserLastName()
						, entity.getUserType()
						, entity.getUserEmail()
						, entity.isLoggedIn()
						? 1
								: 0);

		String sqlQuery =
				String.format(
						SQLQueries.INSERT_INTO__TABLENAME__VALUES__
						, TableNames.USER
						, valuesSet);

		try
		{
			result = DBAdapter.getAdapter().save(sqlQuery);
		}
		catch ( SQLException e )
		{
			e.printStackTrace();
		}

		return result;
	}

	@Override
	public boolean refresh ( String sqlQuery )
	{
		boolean success = false;

		try
		{
			success = DBAdapter.getAdapter().refresh(sqlQuery);
		}
		catch ( SQLException e )
		{
			e.printStackTrace();
		}
		return success;
	}

	@Override
	public boolean deleteByID ( int ID )
	{
		return this.deleteByID(String.valueOf(ID));
	}

	@Override
	public boolean deleteByID ( String ID )
	{
		String sqlQuery =
				String.format(
						SQLQueries.DELETE_FROM__TABLENAME__WHERE__COMPARE_
						, TableNames.USER
						, UserTable.ID + "=" + ID);

		boolean success = false;
		try
		{
			success = DBAdapter.getAdapter().delete(sqlQuery);
		}
		catch ( SQLException e )
		{
			e.printStackTrace();
		}

		return success;
	}

	/**
	 * for testing tables
	 * @param args
	 */
	public static void main ( String[] args )
	{
		System.out.println("******************TESTING UserDAO***************");
		UserDAO testUserDAO = new UserDAO();
		User testUser = testUserDAO.create();

		testUser.setUserID(33278938);
		testUser.setPassword("mypassword");
		testUser.setUserFirstName("Rabea");
		testUser.setUserLastName("Jubran");
		testUser.setUserType(UserType.CUSTOMER);
		testUser.setUserEmail("rabea.jubran@vcp.com");
		testUser.setLoggedIn(false);
		testUserDAO.save(testUser);

		System.out.println("USer 1 was saved");
		System.out.println("*********************************************************");

		User testUser1 = testUserDAO.create();
		testUser1.setUserID(12345678);
		testUser1.setPassword("mypassword");
		testUser1.setUserFirstName("Abcd");
		testUser1.setUserLastName("Jubran");
		testUser1.setUserType(UserType.CUSTOMER);
		testUser1.setUserEmail("Abcd.jubran@vcp.com");
		testUser1.setLoggedIn(false);
		testUserDAO.save(testUser1);

		System.out.println("USer 2 was saved");

		System.out.println("*********************************************************");

		testUser = testUserDAO.findByID(12345678);
		System.out.println("User with id:" + testUser1.getUserID() +
				" was found");
		System.out.println("*********************************************************");

		testUserDAO.updatedLoggedInStatus(testUser.getUserID(), false);
		System.out.println("user with id:" + testUser.getUserID() +
				" was updated");
		testUserDAO.updatedLoggedInStatus(testUser1.getUserID(), true);
		System.out.println("user with id:" + testUser1.getUserID() +
				" was updated");

		System.out.println("*********************************************************");

		for ( User foundUser : testUserDAO.findAll(null) )
		{
			System.out.println("User with id:" + foundUser.getUserID() +
					" was found");
		}

		System.out.println("*********************************************************");

		for ( User foundUser : testUserDAO.findAllLoggedIn() )
		{
			System.out.println("User with id:" + foundUser.getUserID() +
					" is logged in");
		}

		System.out.println("*********************************************************");

		testUserDAO.deleteByID(33278938);
		testUserDAO.deleteByID(12345678);
		System.out.println("USer was deleted");
	}

}
